package tt.dz.biz.service.rpc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.apache.avro.Protocol;
import org.apache.avro.Protocol.Message;
import org.apache.avro.generic.GenericRecord;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import tt.dz.biz.service.oper.OperService;
import tt.dz.biz.service.user.OperListService;
import tt.dz.biz.service.user.OperRoleService;
import tt.dz.biz.service.user.RoleService;
import tt.dz.biz.service.user.SystemInfoService;
import tt.dz.common.BusinessException;
import tt.dz.common.DZStringUtil;
import tt.dz.common.DateUtil;
import tt.dz.common.DzConstants;
import tt.dz.common.DzConstants.gender;
import tt.dz.common.DzDigester;
import tt.dz.common.DzErrorCode;
import tt.dz.common.DzErrorCode.CommonErrorCode;
import tt.dz.common.DzErrorCode.ExceptionErrorCode;
import tt.dz.common.DzErrorCode.UserErrorCode;
import tt.dz.common.LogUtil;
import tt.dz.common.RPCUtil;
import tt.dz.vo.OperListVO;
import tt.dz.vo.OperRoleVO;
import tt.dz.vo.Operator;
import tt.dz.vo.RoleVO;
import tt.dz.vo.SystemInfoVO;
import tt.dz.vo.request.BaseRpcRequestVo;
import tt.dz.vo.request.QueryOperUserBaseInfoRpcRequestVo;
import tt.dz.vo.response.OperInfoRes;

@Service("rpcOperUserService")
public class RPCOperUserService
  implements RPCBaseService
{
  @Resource(name="operListService")
  private OperListService operListService;
  @Resource(name="operService")
  private OperService operService;
  @Resource(name="systemInfoService")
  private SystemInfoService systemInfoService;
  @Resource(name="operRoleService")
  private OperRoleService operRoleService;
  @Resource(name="roleService")
  private RoleService roleService;
  @Resource(name="rpcMsVerifyCodeService")
  private RPCMsVerifyCodeService rpcMsVerifyCodeService;
  @Value("${identityAccountKey}")
  private String identityAccountKey;
  
  public Object execute(Protocol.Message message, Object request, Protocol protocol)
    throws Exception
  {
    String name = message.getName();
    Object reqJson = ((GenericRecord)request).get("req");
    String resJson = "";
    if ("addSysUser".equals(name)) {
      resJson = addSysUser(reqJson.toString());
    } else if ("forgotPassword".equals(name)) {
      resJson = forgotPassword(reqJson.toString());
    } else if ("modifyOperRole".equals(name)) {
      resJson = modifyOperRole(reqJson.toString());
    } else if ("modifyOperInfo".equals(name)) {
      resJson = modifyOperInfo(reqJson.toString());
    } else if ("queryOperUserBaseInfo".equals(name)) {
      resJson = queryOperUserBaseInfo(reqJson.toString());
    }
    if (resJson == null) {
      resJson = RPCUtil.generateResponseObject(Integer.valueOf(0), DzErrorCode.ExceptionErrorCode.COMMON_EXCEPTION.value(), DzErrorCode.ExceptionErrorCode.COMMON_EXCEPTION.getDesc()).toString();
    }
    return resJson;
  }
  
  private String queryOperUserBaseInfo(String reqJson)
  {
    JSONObject resultJson = null;
    String queryById = "1";
    String queryByName = "2";
    String queryByMobile = "3";
    String queryByNickName = "4";
    try
    {
      QueryOperUserBaseInfoRpcRequestVo vo = (QueryOperUserBaseInfoRpcRequestVo)BaseRpcRequestVo.convertAndValidateVo(reqJson, QueryOperUserBaseInfoRpcRequestVo.class);
      OperListVO operListVO = new OperListVO();
      String queryValue = vo.getQueryValue();
      String queryType = vo.getQueryType();
      if (queryById.equals(queryType))
      {
        operListVO.setManagerId(queryValue);
      }
      else if (queryByName.equals(queryType))
      {
        operListVO.setName(queryValue);
      }
      else if (queryByMobile.equals(queryType))
      {
        operListVO.setMobileNo(queryValue);
      }
      else if (queryByNickName.equals(queryType))
      {
        operListVO.setNickName(queryValue);
      }
      else
      {
        DzErrorCode.CommonErrorCode e = DzErrorCode.CommonErrorCode.PARAM_FORMAT_ERROR;
        throw new BusinessException(e.value(), e.getDesc(), "异常的查询方式");
      }
      List<OperListVO> operList = this.operListService.queryOperListNotLike(operListVO);
      List<OperInfoRes> results = new ArrayList();
      OperInfoRes res;
      if ((operList != null) && (!operList.isEmpty()))
      {
        res = null;
        for (OperListVO oPvo : operList)
        {
          res = new OperInfoRes();
          res.setManagerId(oPvo.getManagerId());
          res.setNickName(oPvo.getNickName());
          res.setMobileNo(oPvo.getMobileNo());
          res.setRegistTime(oPvo.getRegistTime());
          res.setEmail(oPvo.getEmail());
          res.setName(oPvo.getName());
          res.setGender(oPvo.getGender());
          res.setIsLocked(oPvo.getIsLocked());
          res.setLockedTime(oPvo.getLockedTime());
          results.add(res);
        }
      }
      resultJson = RPCUtil.generateResponseObject(Integer.valueOf(1), null, null);
      resultJson.put("result", results);
    }
    catch (BusinessException e)
    {
      resultJson = RPCUtil.generateResponseObject(Integer.valueOf(0), e.getStatusCode(), e.getStatusDescribe());
    }
    catch (Exception e)
    {
      resultJson = RPCUtil.generateResponseObject(Integer.valueOf(0), DzErrorCode.ExceptionErrorCode.COMMON_EXCEPTION.value(), DzErrorCode.ExceptionErrorCode.COMMON_EXCEPTION.getDesc());
    }
    return resultJson.toString();
  }
  
  public String forgotPassword(String reqJson)
    throws Exception
  {
    JSONObject resObj = new JSONObject();
    JSONObject reqObj = JSON.parseObject(reqJson);
    String moboleNo = reqObj.getString("moboleNo");
    String verifyCode = reqObj.getString("verifyCode");
    String password = reqObj.getString("password");
    JSONObject verifyreqObj = new JSONObject();
    verifyreqObj.put("mobileNo", moboleNo);
    verifyreqObj.put("checkCode", verifyCode);
    JSONObject verifyresObj = this.rpcMsVerifyCodeService.verifyCheckCode(reqObj);
    String isSucess = verifyresObj.getString("isSuccess");
    if ("1".equals(isSucess))
    {
      OperListVO operVo = this.operListService.queryOper(moboleNo);
      if (operVo != null)
      {
        operVo.setPassword(DzDigester.sha1ForOper(password));
        this.operListService.updateOperList(operVo);
      }
      else
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_FORMAT_ERROR.value());
        resObj.put("errorMsg", "用户" + moboleNo + "不存在！");
        return JSON.toJSONString(resObj);
      }
    }
    else
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_FORMAT_ERROR.value());
      resObj.put("errorMsg", "短信验证码不正确");
      return JSON.toJSONString(resObj);
    }
    resObj.put("isSuccess", Integer.valueOf(1));
    return JSON.toJSONString(resObj);
  }
  
  public String addSysUser(String reqJson)
    throws Exception
  {
    JSONObject resObj = new JSONObject();
    JSONObject reqObj = JSON.parseObject(reqJson);
    String sysCode = reqObj.getString("sysCode");
    List<Object> roleList = reqObj.getJSONArray("roleList");
    String mobileNo = reqObj.getString("mobileNo");
    String nickName = reqObj.getString("nickName");
    String password = reqObj.getString("password");
    String email = reqObj.getString("email");
    String createdBy = reqObj.getString("createdBy");
    String name = reqObj.getString("name");
    String decPassword = null;
    if (StringUtils.isBlank(sysCode))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "sysCode为必传参数！");
      return JSON.toJSONString(resObj);
    }
    if (CollectionUtils.isEmpty(roleList))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "roleList为必传参数！");
      return JSON.toJSONString(resObj);
    }
    if (StringUtils.isBlank(mobileNo))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "手机号码【mobileNo】不能为空。");
      return JSON.toJSONString(resObj);
    }
    if ((StringUtils.isNotBlank(mobileNo)) && (!DZStringUtil.verifyMobileNo(mobileNo)))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.MOBILE_NO_FORMAT_ERROR.value());
      resObj.put("errorMsg", "mobileNo【" + mobileNo + "】格式不正确！");
      return JSON.toJSONString(resObj);
    }
    if ((StringUtils.isNotBlank(nickName)) && (!DZStringUtil.verifyUserName(nickName)))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.UserErrorCode.NICK_NAME_FORMAT_ERROR.value());
      resObj.put("errorMsg", "nickName【" + nickName + "】格式不正确，应该是字母数字下划线");
      return JSON.toJSONString(resObj);
    }
    if ((StringUtils.isNotBlank(email)) && (!DZStringUtil.verifyEmail(email)))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.EMAIL_FORMAT_ERROR.value());
      resObj.put("errorMsg", "email【" + email + "】格式不正确！");
      return JSON.toJSONString(resObj);
    }
    if (StringUtils.isNotBlank(mobileNo))
    {
      OperListVO param = new OperListVO();
      param.setMobileNo(mobileNo);
      List<OperListVO> existOperList = this.operListService.queryOperListNotLike(param);
      if (CollectionUtils.isNotEmpty(existOperList))
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.UserErrorCode.OPER_EXISTS.value());
        resObj.put("errorMsg", "存在相同手机号码【mobileNo=" + mobileNo + "】的操作员，请确认后再试。");
        return JSON.toJSONString(resObj);
      }
    }
    if (StringUtils.isNotBlank(nickName))
    {
      OperListVO param = new OperListVO();
      param.setNickName(nickName);
      List<OperListVO> existOperList = this.operListService.queryOperListNotLike(param);
      if (CollectionUtils.isNotEmpty(existOperList))
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.UserErrorCode.OPER_EXISTS.value());
        resObj.put("errorMsg", "存在相同昵称【nickName=" + nickName + "】的操作员，请确认后再试。");
        return JSON.toJSONString(resObj);
      }
    }
    if (StringUtils.isNotBlank(email))
    {
      OperListVO param = new OperListVO();
      param.setEmail(email);
      List<OperListVO> existOperList = this.operListService.queryOperListNotLike(param);
      if (CollectionUtils.isNotEmpty(existOperList))
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.UserErrorCode.OPER_EXISTS.value());
        resObj.put("errorMsg", "存在有相同邮件【email=" + email + "】的操作员，请确认后再试。");
        return JSON.toJSONString(resObj);
      }
    }
    if (StringUtils.isBlank(password))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "password为必传参数！");
      return JSON.toJSONString(resObj);
    }
    try
    {
      decPassword = DzDigester.desDecrypt(password, this.identityAccountKey);
      if (StringUtils.isBlank(decPassword))
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
        resObj.put("errorMsg", "password解密失败！");
        return JSON.toJSONString(resObj);
      }
    }
    catch (Exception e)
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "password解密失败！");
      return JSON.toJSONString(resObj);
    }
    if (StringUtils.isBlank(createdBy))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "createdBy为必传参数！");
      return JSON.toJSONString(resObj);
    }
    Operator opera = this.operService.queryOperatorByID(createdBy);
    if (opera == null)
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.CREATEBY_NOT_FOUNT.value());
      resObj.put("errorMsg", "查询不到createdBy:" + createdBy + "的操作人员信息，请核实！");
      return JSON.toJSONString(resObj);
    }
    SystemInfoVO systemInfoVo = this.systemInfoService.querySystemInfoById(sysCode);
    if (systemInfoVo == null)
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.SYSCODE_NOT_FOUNT.value());
      resObj.put("errorMsg", "查询不到sysCode:" + sysCode + "的系统信息，请核实！");
      return JSON.toJSONString(resObj);
    }
    for (Object roleId : roleList)
    {
      RoleVO roleVo = this.roleService.queryRoleByID(String.valueOf(roleId), sysCode);
      if (roleVo == null)
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.UserErrorCode.ROLE_NOT_FOUNT.value());
        resObj.put("errorMsg", "角色：roleId:" + roleId + ";sysCode:" + sysCode + "不存在，请核实！");
        return JSON.toJSONString(resObj);
      }
    }
    OperListVO operListVo = this.operListService.queryOper(mobileNo);
    if (operListVo != null)
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.UserErrorCode.OPER_EXISTS.value());
      resObj.put("errorMsg", "操作员：mobileNo:" + mobileNo + "已经存在，请核实！");
      return JSON.toJSONString(resObj);
    }
    OperListVO operListVO = new OperListVO();
    operListVO.setMobileNo(mobileNo);
    operListVO.setPassword(decPassword);
    operListVO.setRegistTime(DateUtil.getDBCurrentTime());
    operListVO.setEmail(email);
    operListVO.setName(name);
    operListVO.setCreatedBy(createdBy);
    operListVO.setCreatedTime(DateUtil.getDBCurrentTime());
    operListVO.setIsLocked(Integer.valueOf(0));
    operListVO.setIsValid(Integer.valueOf(1));
    boolean roleSaved = false;
    boolean operSaved = this.operListService.insertOperList(operListVO);
    if (operSaved)
    {
      List<OperRoleVO> operRoleList = new ArrayList();
      OperRoleVO operRoleVO = null;
      for (Object roleId : roleList)
      {
        operRoleVO = new OperRoleVO();
        operRoleVO.setManagerId(operListVO.getManagerId());
        operRoleVO.setRoleId(String.valueOf(roleId));
        operRoleVO.setSysCode(sysCode);
        operRoleVO.setIsValid(Integer.valueOf(1));
        operRoleList.add(operRoleVO);
      }
      roleSaved = this.operRoleService.modifyOperRole(operRoleList, operListVO.getManagerId());
    }
    if ((operSaved) && (roleSaved))
    {
      resObj.put("userId", operListVO.getManagerId());
      resObj.put("isSuccess", Integer.valueOf(1));
      return JSON.toJSONString(resObj);
    }
    resObj.put("isSuccess", Integer.valueOf(0));
    resObj.put("errorCode", DzErrorCode.UserErrorCode.SAVE_UNKNOWN_ERROR.value());
    resObj.put("errorMsg", "保存发生未知错误，请与管理员联系！");
    return JSON.toJSONString(resObj);
  }
  
  public String modifyOperRole(String reqJson)
  {
    JSONObject resObj = new JSONObject();
    JSONObject reqObj = JSON.parseObject(reqJson);
    String sysCode = reqObj.getString("sysCode");
    List<Object> roleIdList = reqObj.getJSONArray("roleIdList");
    String managerId = reqObj.getString("userId");
    String oper = reqObj.getString("oper");
    if (StringUtils.isBlank(sysCode))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "sysCode为必传参数！");
      return JSON.toJSONString(resObj);
    }
    if (StringUtils.isBlank(managerId))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "managerId为必传参数！");
      return JSON.toJSONString(resObj);
    }
    if (StringUtils.isBlank(oper))
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
      resObj.put("errorMsg", "oper为必传参数！");
      return JSON.toJSONString(resObj);
    }
    try
    {
      Operator tmp = this.operService.queryOperatorByID(managerId);
      if (null == tmp)
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.UserErrorCode.USER_NOT_FOUND.value());
        resObj.put("errorMsg", "用户id（userId：" + managerId + "）不存在！");
        return JSON.toJSONString(resObj);
      }
      tmp = this.operService.queryOperatorByID(oper);
      if (null == tmp)
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.UserErrorCode.USER_NOT_FOUND.value());
        resObj.put("errorMsg", "操作人员（oper" + oper + "）不存在！");
        return JSON.toJSONString(resObj);
      }
      List<OperRoleVO> operRoleList = new ArrayList();
      OperRoleVO operRole = null;
      for (Object obj : roleIdList)
      {
        operRole = new OperRoleVO();
        operRole.setUpdatedBy(oper);
        operRole.setManagerId(managerId);
        operRole.setUpdatedTime(DateUtil.getDBCurrentTime());
        operRole.setSysCode(sysCode);
        operRole.setIsValid(Integer.valueOf(1));
        operRole.setRoleId(obj.toString());
        operRoleList.add(operRole);
      }
      for (OperRoleVO operRoleVO : operRoleList)
      {
        RoleVO roleVo = this.roleService.queryRoleByID(operRoleVO.getRoleId(), sysCode);
        if (null == roleVo)
        {
          resObj.put("isSuccess", Integer.valueOf(0));
          resObj.put("errorCode", DzErrorCode.UserErrorCode.ROLE_NOT_FOUNT.value());
          resObj.put("errorMsg", "角色：roleId:" + operRoleVO.getRoleId() + ";sysCode:" + sysCode + "不存在，请核实！");
          return JSON.toJSONString(resObj);
        }
      }
      this.operRoleService.modifyOperRoleForBizSystem(managerId, sysCode, operRoleList);
      resObj.put("isSuccess", Integer.valueOf(1));
      return JSON.toJSONString(resObj);
    }
    catch (Exception e)
    {
      resObj.put("isSuccess", Integer.valueOf(0));
      resObj.put("errorCode", DzErrorCode.ExceptionErrorCode.COMMON_EXCEPTION.value());
      resObj.put("errorMsg", DzErrorCode.ExceptionErrorCode.COMMON_EXCEPTION.getDesc());
    }
    return JSON.toJSONString(resObj);
  }
  
  private String modifyOperInfo(String reqJson)
    throws Exception
  {
    JSONObject resObj = new JSONObject();
    try
    {
      JSONObject reqObj = JSON.parseObject(reqJson);
      String managerId = reqObj.getString("userId");
      String oper = reqObj.getString("oper");
      String sysCode = reqObj.getString("sysCode");
      if (StringUtils.isBlank(sysCode))
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
        resObj.put("errorMsg", "sysCode为必传参数！");
        return JSON.toJSONString(resObj);
      }
      if (StringUtils.isBlank(managerId))
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
        resObj.put("errorMsg", "managerId为必传参数！");
        return JSON.toJSONString(resObj);
      }
      if (StringUtils.isBlank(oper))
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.CommonErrorCode.PARAM_REQUIRED.value());
        resObj.put("errorMsg", "oper为必传参数！");
        return JSON.toJSONString(resObj);
      }
      OperListVO operListVO = (OperListVO)JSON.parseObject(reqJson, OperListVO.class);
      if ((null != operListVO.getGender()) && 
        (!DzConstants.gender.FEMALE.value().equals(operListVO.getGender())) && 
        (!DzConstants.gender.MALE.value().equals(operListVO.getGender())))
      {
        resObj.put("isSuccess", Integer.valueOf(0));
        resObj.put("errorCode", DzErrorCode.CommonErrorCode.GENDER_ERROR.value());
        resObj.put("errorMsg", "性别必须为0（女）或1（男）");
        return JSON.toJSONString(resObj);
      }
      operListVO.setManagerId(managerId);
      operListVO.setUpdatedBy(oper);
      int n = this.operService.updateOper(operListVO);
      if (n < 1) {
        throw new BusinessException(DzErrorCode.CommonErrorCode.SAVE_ERROR.value(), DzErrorCode.CommonErrorCode.SAVE_ERROR.getDesc(), DzErrorCode.CommonErrorCode.SAVE_ERROR.getDesc());
      }
      resObj.put("isSuccess", Integer.valueOf(1));
      return JSON.toJSONString(resObj);
    }
    catch (Exception e)
    {
      LogUtil.error("更新操作人员信息异常，参数为：reqJson=" + reqJson, e);
      throw e;
    }
  }
}
